#include "built_effect.h"
#include "bsp.h"

struct color base_color[] = {
    {0, 0, 0},       // 黑
    {128, 0, 0},     // 红
    {128, 128, 0},   // 黄
    {0, 128, 0},     // 绿
    {0, 128, 128},   // 青
    {0, 0, 128},     // 蓝
    {128, 0, 128},   // 紫
    {128, 128, 128}, // 白
    {255, 128, 1}    // test
};

uint8_t led_rgb_data[PIXEL_PER_CHAN*3];

void fill_strip_with_color(uint8_t* buff, uint16_t leds, struct color c)
{
    uint16_t led_num = leds;

    if (leds > PIXEL_PER_CHAN)
        led_num = PIXEL_PER_CHAN;

    for (uint16_t i = 0; i < led_num; i++)
    {
        buff[3 * i] = c.r;
        buff[3 * i + 1] = c.g;
        buff[3 * i + 2] = c.b;
    }
}


// ws2812 24个位一个灯,
// 要将 color_buffer 的 RGB数据转换成 spi编码的数据
// 对应的关系是 spi的一个字节表示 ws2812的2个位
// 比如说 要将颜色#FFFFFF 转换成编码数据对应的spi编码数据位：
// 0xee 0xee, 0xee, 0xee, 0xee, 0xee, 0xee, 0xee,  0xee, 0xee, 0xee, 0xee

// 可以将spi模拟 ws2812 2位 数据的字节取值情况枚举出来: 
// 00 -> 0x88
// 01 -> 0x8e
// 10 -> 0xe8
// 11 -> 0xee
// 请你实现上面的编码函数，将全局的led_rgb_data编码成全局的 ws2812_buffer;

//const uint8_t ws2812_spi_map[4] = {0x88, 0x8e, 0xe8, 0xee}; // 00, 01, 10, 11

//void ws2812_data_encode_spi(uint8_t *data, uint16_t led_cnt) {
//    
//    if (data == NULL || led_cnt == 0) {
//        return; 
//    }

//    if (led_cnt > WS2812_NUM_LEDS) {
//        led_cnt = WS2812_NUM_LEDS; // 限制为最大灯数
//    }

//    for (uint16_t ch = 0; ch < led_cnt; ch++) {
//        uint16_t rgb_offset = ch * 3;
//        uint16_t buffer_offset = ch * 12;
//        uint16_t buffer_idx = buffer_offset;

//        for (uint8_t color_idx = 0; color_idx < 3; color_idx++) {
//            uint8_t color_byte = data[rgb_offset + color_idx];
//            for (uint8_t bit_pair = 0; bit_pair < 4; bit_pair++) {
//                uint8_t bits = (color_byte >> (6 - bit_pair * 2)) & 0x03;
//                ws2812_buffer[buffer_idx++] = ws2812_spi_map[bits];
//            }
//        }
//    }
//}
//void ws2812_turn_off_all(void)
//{
//    fill_strip_with_color(led_rgb_data, WS2812_NUM_LEDS, base_color[0]);
//    ws2812_data_encode_spi(led_rgb_data, WS2812_NUM_LEDS);
//    ws2812_send_data_spi(WS2812_BUFFER_SIZE);
//}


//void ws2812_test(void)
//{
//    static uint8_t idx = 0;
//    idx = (idx + 1) % (sizeof(base_color) / sizeof(base_color[0])); 

//    fill_strip_with_color(led_rgb_data, WS2812_NUM_LEDS, base_color[idx]);

//    ws2812_data_encode_spi(led_rgb_data, WS2812_NUM_LEDS);

//    while (ws2821_spi_send_done != 1)
//        ;

//    ws2812_send_data_spi(WS2812_BUFFER_SIZE);
//}


uint8_t led_ch_data[CHAN_MAX][BUF_SIZE_PER_CHAN] = {0};
void ws2812_encode_data(const uint8_t* input, uint8_t* output, const uint16_t led_chn)
{
    uint16_t oput_idx = 0;

    for (uint16_t iput_idx = 0; iput_idx < led_chn; iput_idx++)
    {
        uint8_t curr_value = input[iput_idx];
        // rt_kprintf("i:%d\t0X%02X  ", iput_idx, curr_value);

        for (uint8_t bit_pos = 0; bit_pos < 8; bit_pos++)
        {
            // Extract each bit from MSB to LSB and store as a byte
            output[oput_idx++] = (curr_value >> (7 - bit_pos)) & 0x01;
            // rt_kprintf("0x%02x ", output[oput_idx - 1]);
        }
        // rt_kprintf("\n");
    }
}

void ws2812_mulch_buffer_set(uint8_t* buffer)
{
    uint16_t i = 0, s = BUF_SIZE_PER_CHAN, x = 0;
    uint8_t  z = 0, h = 0;
    uint8_t  TEMP1, TEMP2, TEMP3, TEMP4, TEMP5, TEMP6, TEMP7, TEMP8, TEMP;

    while (s)
    {

        TEMP1 = buffer[i];
        TEMP2 = buffer[i];
        TEMP3 = buffer[i];
        TEMP4 = buffer[i];
        TEMP5 = buffer[i];
        TEMP6 = buffer[i];
        TEMP7 = buffer[i];
        TEMP8 = buffer[i];

        // 将像素效果的数据拆成8个字节，其中每一个位代表一个通道的高低电平状态
        // 举个例子：8个通道，每个通道1个灯，显示红灯效果静态效果，原数据8组 FF 00 00，
        // 编码之后会占用 3 * 8个字节：
        // idx  0 ->  7:
        // idx  8 -> 15:
        // idx 16 -> 23:
        while (z < 8)
        {
            h = 7 - z;

            // BIT7, PIN7
            TEMP = TEMP8 >> (h)&0x1;

            // BIT6, PIN6
            TEMP = TEMP << 1;
            TEMP |= TEMP7 >> (h)&0x1;

            TEMP = TEMP << 1;
            TEMP |= TEMP6 >> (h)&0x1;

            TEMP = TEMP << 1;
            TEMP |= TEMP5 >> (h)&0x1;

            TEMP = TEMP << 1;
            TEMP |= TEMP4 >> (h)&0x1;

            TEMP = TEMP << 1;
            TEMP |= TEMP3 >> (h)&0x1;

            TEMP = TEMP << 1;
            TEMP |= TEMP2 >> (h)&0x1;

            TEMP = TEMP << 1;
            TEMP |= TEMP1 >> (h)&0x1;

            led_driver_bitstream[x] = TEMP;
            x++;
            z++;
        }
        i++;
        z = 0;
        s--;
    }
}

void ws2812_test(void)
{

    static uint8_t idx = 0;
    idx = (idx + 1) % (sizeof(base_color) / sizeof(base_color[0]));

    fill_strip_with_color(led_ch_data[0], PIXEL_PER_CHAN, base_color[idx]);
    ws2812_mulch_buffer_set(led_ch_data[0]);

    while (led_send_done != 1)
        ;
    ws2812_send_data(g_led_chn_count * 8);
}
